\documentclass[C:/Users/12748/Desktop/latex模板/main/main.tex]{subfiles}
\begin{document}

\begin{itemize}
\item
  \texttt{1\ l\ r\ x}：将 \(A_l,...,A_r\) 中每个元素二进制与上一个数
\item
  \texttt{2\ l\ r\ x}：将 \(A_l,...,A_r\) 中每个元素二进制或上一个数
\item
  \texttt{3\ l\ r}：求 \(A_l,...,A_r\) 中的最小值
\item
  \(1\leq n,m \leq 5\times 10^5\)，\(0\leq A_i,x_i \leq 10^9\)
\end{itemize}

\begin{lstlisting}
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10 , ALL = (1ll << 31) - 1;
int n, a[N];
struct Node
{
	int l , r;
	int mi, v0, v1;
} tree[N << 2];
inline void push_up(int rt)
{
	tree[rt].v1 = tree[rt << 1].v1 & tree[rt << 1 | 1].v1;
	tree[rt].v0 = tree[rt << 1].v0 & tree[rt << 1 | 1].v0;
	tree[rt].mi = min(tree[rt << 1].mi, tree[rt << 1 | 1].mi);
}
void build(int rt, int l, int r)
{
	tree[rt].l = l , tree[rt].r = r;
	if (l == r)
	{
		tree[rt].mi = tree[rt].v1 = a[l], tree[rt].v0 = ALL ^ a[l];
		return;
	}
	int mid = l + r >> 1;
	build(rt << 1 , l , mid);
	build(rt << 1 | 1 , mid + 1, r);
	push_up(rt);
}
void push_down(int rt)
{
	if((tree[rt].v0 | tree[rt].v1) == ALL) 
	{
		tree[rt << 1].mi = tree[rt << 1 | 1].mi = tree[rt].mi;
		tree[rt << 1].v0 = tree[rt << 1 | 1].v0 = tree[rt].v0;
		tree[rt << 1].v1 = tree[rt << 1 | 1].v1 = tree[rt].v1;
	}
}
void query_Or(int rt, int L, int R, int v)
{
	v &= ALL ^ tree[rt].v1;
	if(!v)	return;
	int l = tree[rt].l , r = tree[rt].r;
	if(L <= l && r <= R)
	{
		if ((v | tree[rt].v1 | tree[rt].v0) == ALL)
		{
			tree[rt].v1 |= v, tree[rt].v0 = ALL ^ tree[rt].v1, tree[rt].mi = tree[rt].v1;
			return;
		}
		push_down(rt);
		query_Or(rt << 1 , L , R , v);
		query_Or(rt << 1 | 1 , L , R , v);
		push_up(rt);
		return;
	}
	push_down(rt);
	int mid = l + r >> 1;
	if(L <= mid) query_Or(rt << 1 , L , R , v);
	if(R  > mid) query_Or(rt << 1 | 1 , L , R , v);
	push_up(rt);
}
void query_And(int rt, int L, int R, int v)
{
	v &= ALL ^ tree[rt].v0;
	if(!v) return;
	int l = tree[rt].l , r = tree[rt].r;
	if(L <= l && r <= R)
	{
		if ((v | tree[rt].v1 | tree[rt].v0) == ALL)
		{
			tree[rt].v0 |= v, tree[rt].v1 = ALL ^ tree[rt].v0, tree[rt].mi = tree[rt].v1;
			return;
		}
		push_down(rt);
		query_And(rt << 1 , L , R , v);
		query_And(rt << 1 | 1 , L , R , v);
		push_up(rt);
		return;
	}
	push_down(rt);
	int mid = l + r >> 1;
	if(L <= mid) query_And(rt << 1 , L , R , v);
	if(R  > mid) query_And(rt << 1 | 1 , L , R , v);
	push_up(rt);
}
int query_min(int rt, int L, int R)
{
	int l = tree[rt].l , r = tree[rt].r;
	if(L <= l && r <= R || ALL == (tree[rt].v0 | tree[rt].v1)) return tree[rt].mi;
	int mid = l + r >> 1 , res = ALL;
	if(L <= mid) res = min(res , query_min(rt << 1, L , R));
	if(R  > mid) res = min(res , query_min(rt << 1 | 1, L , R));
	return res;
}
signed main()
{
	int n , m;
	cin >> n >> m;
	for (int i = 1 ; i <= n ; i ++) cin >> a[i];
	build(1 , 1 , n);
	while(m --)
	{
		int op , L , R , x;
		cin >> op >> L >> R;
		if(op == 1) 
		{
			cin >> x;
			query_And(1, L, R, (ALL ^ x));
		}
		if(op == 2) 
		{
			cin >> x;
			query_Or(1, L, R, x);
		}
		if(op == 3) cout << query_min(1 , L , R) << '\n';
	}
	return 0;
}
\end{lstlisting}


\end{document}
